package cn.vc.wallet.service.impl;

import cn.vc.basicmodule.entity.Result;
import cn.vc.wallet.entity.dto.WalletDto;
import cn.vc.wallet.entity.po.Wallet;
import cn.vc.wallet.mapper.WalletMapper;
import cn.vc.wallet.service.WalletService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author mo
 * @Description:
 * @日期: 2024-04-20 18:04
 **/
@Service
public class WalletServiceImpl implements WalletService {
    // KEY{id}
    private final static String MY_WALLET_DTO_KEY = "wallet/my_wallet_dto:";

    @Autowired
    private WalletMapper walletMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void createWallet(Long id) {
        Wallet wallet = new Wallet();
        wallet.setId(id);
        wallet.setCoin(0L);
        wallet.setDiamond(0L);
        walletMapper.insert(wallet);
    }

    @Override
    public Result<Integer> signIn(Long id) {
        //随机生成1~10个金币
        Random r = new Random();
        int coin = r.nextInt(10)+1;
        //添加金币
        Wallet wallet = walletMapper.selectById(id);
        if (wallet==null) return new Result<>(0, null, "签到失败！");
        // 从未签过到
        if (wallet.getSigninTime()==null) {
            wallet.setSigninTime(new Timestamp(System.currentTimeMillis()));
            wallet.setCoin(wallet.getCoin()+coin);
            walletMapper.updateById(wallet);
            // 删除缓存
            stringRedisTemplate.delete(MY_WALLET_DTO_KEY+id);
            return new Result<>(1, coin, "签到成功！");
        } else {
            // 判断当天是否签过
            boolean bo = isSameDate(wallet.getSigninTime().getTime(), System.currentTimeMillis());
            // 签过
            if (bo) {
                return new Result<>(0, null, "今天已经签过了！");
            }
            // 未签过
            else {
                wallet.setSigninTime(new Timestamp(System.currentTimeMillis()));
                wallet.setCoin(wallet.getCoin()+coin);
                walletMapper.updateById(wallet);
                // 删除缓存
                stringRedisTemplate.delete(MY_WALLET_DTO_KEY+id);
                return new Result<>(1, coin, "签到成功！");
            }
        }
    }


    @Override
    public boolean updateCoin(Long id, int coin) {
        Wallet wallet = walletMapper.selectById(id);
        wallet.setCoin(wallet.getCoin()+coin);
        // 删除缓存
        stringRedisTemplate.delete(MY_WALLET_DTO_KEY+id);
        return walletMapper.updateById(wallet)==1;
    }

    @Override
    public WalletDto selectById(Long id) {
        WalletDto walletDto = JSON.parseObject(stringRedisTemplate.opsForValue().get(MY_WALLET_DTO_KEY +id), WalletDto.class);
        if (walletDto==null) {
            Wallet wallet = walletMapper.selectById(id);
            if (wallet!=null) {
                walletDto = new WalletDto();
                BeanUtils.copyProperties(wallet, walletDto);
                // 判断当天是否签到过
                if (wallet.getSigninTime()!=null) {
                    walletDto.setSignin(isSameDate(wallet.getSigninTime().getTime(), System.currentTimeMillis()));
                } else {
                    walletDto.setSignin(false);
                }
                stringRedisTemplate.opsForValue().set(MY_WALLET_DTO_KEY +id, JSON.toJSONString(walletDto), 30, TimeUnit.SECONDS);
            }
        }
        return walletDto;
    }

    @Override
    public Long goldExchange(Long id, Long diamond) {
        Wallet wallet = walletMapper.selectById(id);
        // 钱包不存在
        if (wallet==null) return 0L;
        // 钻石过少，不能兑换
        if (wallet.getDiamond()<diamond) return 0L;
        wallet.setDiamond(wallet.getDiamond()-diamond);
        Long coins = diamond*10;
        wallet.setCoin(wallet.getCoin()+coins);
        walletMapper.updateById(wallet);
        // 删除缓存
        stringRedisTemplate.delete(MY_WALLET_DTO_KEY+id);
        return coins;
    }

    @Override
    public boolean diamondDeduction(Long id, Long diamond) {
        Wallet wallet = walletMapper.selectById(id);
        if (wallet==null || wallet.getDiamond() < diamond) return false;
        LambdaUpdateWrapper<Wallet> luw = new LambdaUpdateWrapper<>();
        luw.eq(Wallet::getId, id);
        luw.set(Wallet::getDiamond, wallet.getDiamond()-diamond);
        return walletMapper.update(null, luw)==1;
    }


    /**
     * 是否为同一天
     * @param a
     * @param b
     * @return
     */
    protected static boolean isSameDate(long a, long b) {
        return a / (24*60*60*1000L) == b / (24*60*60*1000L);
    }

}
